<?php

namespace app\api\controller\xmwechat;

use app\admin\model\member\Rights;
use app\common\model\User;
use app\api\controller\Houses;
use app\common\controller\Frontend;
use app\common\library\xmwechat\payment\PayService;
use app\common\model\Findstore;
use app\common\model\Orders;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\RuntimeException;
use EasyWeChat\Pay\Application;
use EasyWeChat\Pay\Message;
use think\facade\Db;
use think\facade\Log;
use think\Request;

class Payment extends Frontend
{
    // 数组中的 pay 请在调试完成后删除，支付接口需要登录
    protected array $noNeedLogin = ['pay', 'notify'];

    protected array $wechatPayConfig;

    public function initialize(): void
    {
        parent::initialize();
        $config = config('xmwechat');
        $this->wechatPayConfig = $config['payment'];
    }

    /**
     * 微信公众号、小程序支付示例
     * 支付接口是需要登录的，测试结束后，请在最上方$noNeedLogin数组中去掉 pay
     * @param Request $request
     * @return void
     * @throws \Exception
     * @author jsjxsz <QQ:1365962177>
     */
    public function pay(Request $request): void
    {
        if ($request->isPost()) {
            // order_no：订单号 body：描述 pay_price：支付金额 openid：用户openid  transaction_no:交易号
            $params = $request->only(['order_no', 'body', 'pay_price', 'openid', 'transaction_no']);
            // miniProgram: 小程序支付； offiAccount： 公众号支付
            $params['pay_type'] = 'miniProgram';
            $result = PayService::getInstance()->pay($params);
            if ($result !== false) {
                $this->success('success', $result);
            } else {
                $this->error('error');
            }
        }
    }

    /**
     * 微信公众号、小程序支付回调
     * 注意仔细看下面的注释内容
     * @author jsjxsz <QQ:1365962177>
     */
    public function notify()
    {
        file_put_contents('pay.txt', file_get_contents('php://input'), FILE_APPEND);
        try {
            $app = new Application([
                'mch_id' => $this->wechatPayConfig['mch_id'],
                'secret_key' => $this->wechatPayConfig['secret_key'],
                'certificate' => root_path() . $this->wechatPayConfig['certificate'],
                'private_key' => root_path() . $this->wechatPayConfig['private_key'],
                'notify_url' => $this->wechatPayConfig['notify_url'],
                'http' => [
                    'throw' => true, // 状态码非 200、300 时是否抛出异常，默认为开启
                    'timeout' => 5.0,
                ],
            ]);
            $server = $app->getServer();
            $server->handlePaid(function (Message $message, \Closure $next) use ($app) {
                $noyifyData = !is_array($message) ? json_decode($message, true) : $message;
                file_put_contents('pay2.txt', $message, FILE_APPEND);

                $pay_time = strtotime($noyifyData['success_time']);
                $time = time();
                $order_no = $noyifyData['out_trade_no'];
                $transaction_id = $noyifyData['transaction_id'];
                $amount = $noyifyData['amount']['payer_total'] / 100;//单位分


                /**
                 * 这里写你自己的逻辑 start
                 */
                // 这里查询你自己的数据表！！！
                $order = (new Orders())->where('order_no', $order_no)->find();
                if (!$order || $order['pay_status'] == 1) {
                    // 如果订单不存在 或者 订单已经支付过了
                    // 告诉微信，我已经处理完了，订单没找到，别再通知我了
                    $order->save([
                        'pay_status' => 1,
                        'paid_time' => $pay_time,
                        'transaction_id' => $transaction_id,
                        'pay_type' => 'wechat',
                    ]);
                    return ['code' => 'SUCCESS', 'message' => '成功'];
                }

                // return_code 表示通信状态，不代表支付状态
                if ($noyifyData['trade_state'] === 'SUCCESS') {
                    // 支付成功
                    if ($order) {
                        if ($order['house_type'] == 'houses') {
                            $houses=(new \app\admin\model\Houses())
                                ->where('id', $order['house_id'])
                                ->find();

                            $uinfo=(new User())->where('id','=',$houses['user_id'])->find();
                            (new \app\admin\model\Houses())->where('id', $order['house_id'])
                                ->update(['order_id' => $order['id']]);
                            $uinfo->setInc('money',$amount*100);
                        } else {
                            (new Findstore())->where('id', $order['house_id'])
                                ->update(['order_id' => $order['id']]);
                            $findstore=(new Findstore())->where('id', $order['house_id'])->find();
                            $uinfo=(new User())->where('id','=',$findstore['user_id'])->find();
                            $uinfo->setInc('money',$amount*100);
                        }
                        $order->save([
                            'pay_status' => 1,
                            'paid_time' => $pay_time,
                            'transaction_id' => $transaction_id,
                            'pay_type' => 'wechat',
                        ]);
                        if($order['house_type']=='isvip'){
                            $vip_rights=(new Rights())->where('id', $order['house_id'])->find();
                            (new User())->where('id','=',$order['user_id'])->save([
                                'isvip'=>1,
                                'expired_time'=>time()+$vip_rights['validity_period']*24*60*60,
                                'last_count'=>$vip_rights['view_items'],
                                'dodayview_items'=>$vip_rights['view_items'],
                            ]);
                        }
                    }
                    // 写你自己的逻辑
                    return ['code' => 'SUCCESS', 'message' => '成功'];
                } else if ($message['result_code'] === 'FAIL') {
                    // 支付失败
                    // 写你自己的逻辑
                    return ['code' => 'SUCCESS', 'message' => '失败'];
                }
                /**
                 * 这里写你自己的逻辑 end
                 */

                return $next($message);
            });
            return $server->serve();
        } catch (InvalidArgumentException|RuntimeException|\ReflectionException|\Throwable $e) {
            file_put_contents('pay3.txt', $e->getMessage(), FILE_APPEND);
            $this->error($e->getMessage());
        }
    }


}
